package com.yangcangclub.commons.mail;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.activation.FileTypeMap;
import javax.activation.MimetypesFileTypeMap;
import javax.mail.Address;
import javax.mail.Multipart;
import javax.mail.NoSuchProviderException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.Message.RecipientType;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import com.yangcangclub.commons.exception.ApolloException;
import com.yangcangclub.commons.result.MessageEnum;
import com.yangcangclub.commons.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 邮件服务实现,发送邮件
 * 
 *
 */
public class MailEngine implements IMailEngine{

	private static Logger logger = LoggerFactory.getLogger(MailEngine.class);

	/** 默认protocal */
	private static final String DEFAULT_PROTOCAL = "smtp";

	/** 默认port */
	private static final int DEFAULT_PORT = -1;

	/** 默认编码 */
	private static final String DEFAULT_ENCODEING = "UTF-8";

	/** 邮件服务核心Session */
	private Session session;

	/** 邮件服务信息 */
	private MailConfig mailConfig;

	/** FileTypeMap参数--附件类型 */
	private List<String> mappings;
	
	/**
	 * 设置邮件服务Session
	 */
	private synchronized void getMailSession() {
		if (this.session == null) {
			this.session = Session.getInstance(mailConfig.getMailProperties());
		}
	}

	/**
	 * 获取邮件服务Transport
	 * @return
	 * @throws NoSuchProviderException
	 */
	private Transport getTransport() throws NoSuchProviderException {
		return session.getTransport(DEFAULT_PROTOCAL);
	}
	
	
	/**
	 * 邮件附件类型
	 * @return
	 */
	private FileTypeMap createFileTypeMap() {
		MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
		if (mappings != null) {
			for (int i = 0; i < mappings.size(); i++) {
				fileTypeMap.addMimeTypes(mappings.get(i));
			}
		}
		return fileTypeMap;
	}

	public boolean sendRegisteMail(String randomNum,String email) {

		if(!StringUtil.checkEmail(email)) {
			throw new ApolloException(MessageEnum.MAIL_FORMAT_ERROR);
		}

		String mailContent = "你的邮件验证码是："+randomNum;
//		String mailContent = "你的邮件验证码是：1234，请输入验证码到壹栈！";
		SimpleMailData expMail = new SimpleMailData();
		expMail.setSubject("【壹栈】");
		expMail.setContent(mailContent);
		List<String> toList = new ArrayList<String>();
		toList.add(email);
		expMail.setToList(toList);



		return  sendMail(expMail);
	}

	/**
	 * 发送简单文本邮件
	 * @param mailData
	 */
	public boolean sendMail(SimpleMailData mailData) {
		if (!mailConfig.isEnable()) {
			return false;
		}
		String msgContent = mailData.getContent();
		// 初始化邮件服务session
		this.getMailSession();
		// 初始化邮件服务transport
		Transport transport = null;
		try {
			transport = this.getTransport();
		} catch (NoSuchProviderException e) {
			e.printStackTrace();
		}
		MimeMessage message = new MimeMessage(this.session);
		try {
			int port = mailConfig.getPort() == 0 ? DEFAULT_PORT : mailConfig.getPort();
			transport.connect(mailConfig.getHost(), port, mailConfig.getUserName(), mailConfig.getPassword());
			// 添加发送人地址
			Address from = new InternetAddress(mailConfig.getUserName());
			message.setFrom(from);

			// 添加收件人地址
			List<String> toList = mailData.getToList();
			Address[] toArray = new Address[toList.size()];
			Iterator<String> addressIt = toList.iterator();
			int index = 0;
			while (addressIt.hasNext()) {
				String name = addressIt.next();
				toArray[index++] = new InternetAddress(name);
			}
			message.setRecipients(RecipientType.TO, toArray);
			
			// 设置抄送人
			List<String> ccList = mailData.getCcList();
			Address[] ccArray = new Address[ccList.size()];
			Iterator<String> ccAddressIt = ccList.iterator();
			int ccIndex = 0;
			while (ccAddressIt.hasNext()) {
				String name = ccAddressIt.next();
				ccArray[ccIndex++] = new InternetAddress(name);
			}
			message.setRecipients(RecipientType.CC, ccArray);
			
			// 设置秘送人
			List<String> bccList = mailData.getBccList();
			Address[] bccArray = new Address[bccList.size()];
			Iterator<String> bccAddressIt = bccList.iterator();
			int bccIndex = 0;
			while (bccAddressIt.hasNext()) {
				String name = bccAddressIt.next();
				bccArray[bccIndex++] = new InternetAddress(name);
			}
			message.setRecipients(RecipientType.BCC, bccArray);			

			// 添加发送日期
			message.setSentDate(new Date());

			// 添加subject,国际化
			message.setSubject(mailData.getSubject(), DEFAULT_ENCODEING);

			// 添加Multipart(空)
			Multipart mp = new MimeMultipart();
			MimeBodyPart mbp = new MimeBodyPart();
			mbp.setContent(msgContent, "text/html;charset=" + DEFAULT_ENCODEING);
			mp.addBodyPart(mbp);

			// 附件
			// 如果附件文件对象存在
			if (mailData.getAttachFile() != null) {
				mbp = new MimeBodyPart();
				mbp.setDisposition(MimeBodyPart.ATTACHMENT);

				// 邮件附件类型
				FileTypeMap fileTypeMap = this.createFileTypeMap();
				List<File> attachFiles = mailData.getAttachFile();
				for (File attachFile : attachFiles) {
					mbp.setFileName(attachFile.getName());
					FileDataSource dataSource = new FileDataSource(attachFile);
					dataSource.setFileTypeMap(fileTypeMap);
					mbp.setDataHandler(new DataHandler(dataSource));
					mp.addBodyPart(mbp);
				}
			}

			message.setContent(mp);

			message.saveChanges();

			// 发送邮件信息
			transport.sendMessage(message, message.getAllRecipients());

			// 关闭transport
			transport.close();
			logger.debug("邮件发送完成!");

			return true;
		} catch (Throwable e) {
			logger.debug("邮件发送失败!");
			e.printStackTrace();
		}
		return false;
	}
	
	/** seters and getters*/
	public void setMailConfig(MailConfig mailConfig) {
		this.mailConfig = mailConfig;
	}
	
	public List<String> getMappings() {
		return mappings;
	}
	
	public void setMappings(List<String> mappings) {
		this.mappings = mappings;
	}
}
